<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>05_模板解析_一般指令</title>
    <style>
      .red {
        color: red;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <p v-text="msg"></p>
      <p v-html="msg"></p>
      <p v-class="className" v-text="msg"></p>
    </div>
    <script src="./js/observer.js"></script>
    <script src="./js/watcher.js"></script>
    <script src="./js/compile.js"></script>
    <script src="./js/mvvm.js"></script>
    <script>
      /*  
        数据代理：
          将data中数据代理this上使用

        模板解析: 
          解析元素上的指令属性和插值语法

          1. 将节点装换成文档碎片节点
            - 创建了文档碎片节点
            - 通过 while 遍历将el的子节点插入文档碎片节点中
            - 返回文档碎片节点

          2. 编译模板
            - 提取文档碎片中所有子节点（childNodes）
            - 对所有子节点进行遍历，一一处理
            - 提取子节点的文本内容
              - 判断是否元素节点
                - 如果是提取元素节点的所有属性节点，进行遍历
                - 提取属性节点的属性名，判断是否是指令属性（v-）
                  - 如果是在判断是否是事件指令（on）
                    - 如果是事件指令：给当前元素绑定事件，设置回调函数
                      - 事件名从指令属性中截取
                      - 回调函数中从methods中获取
                      - 回调函数通过bind方法改变this指向为vm实例
                  - 还是一般指令
                    - 最终会找到相应指令的updater方法，去更新DOM元素
                      - 比如：v-text，找到textUpdater更新方法，最终通过textContent属性更新元素文本内容
                      - v-html,找到htmlUpdater更新方法，最终通过innerHTML属性更新元素文本内容
                  - 指令解析完成，会从元素上被移除掉

              - 进行判断是否是文本节点，并且里面的文本内容满足插值语法
                - 如果是，就需要对插值语法进行解析
                  - 内部调用多个方法，最终取出一个用来更新DOM元素的updater函数
                  - 从vm上读取表达式的值
                  - 调用updater方法更新元素的textContent为表达式的值
                  - 到此插值语法就解析完毕了
                  - 插值语法解析后面和v-text指令解析是一致的，最终调用textUpdater更新方法，去更新DOM元素

            - 最终，都要对当前子节点的所有子节点进行递归遍历，确保所有节点都进行了编译  

          3. 将编译后的模板放入el中生效
      */
      debugger;
      new MVVM({
        // el: "#app",
        el: document.getElementById("app"),
        data: {
          msg: "<span>hello msg</span>",
          className: "red",
        },
      });
    </script>
  </body>
</html>
